const Point = @import("../point.zig");
const std = @import("std");

/// This holds the mass data computed for a shape.
pub const MassData = struct {
    /// The mass of the shape, usually in kilograms.
    mass: f32,

    /// The position of the shape's centroid relative to the shape's origin.
    center: Point,

    /// The rotational inertia of the shape about the local origin.
    rotational_inertia: f32,

    pub fn init(mass: f32, center: Point, rotational_inertia: f32) MassData {
        const t = MassData{
            .mass = mass,
            .center = center,
            .rotational_inertia = rotational_inertia,
        };

        std.debug.print("{d}\n", .{@intFromPtr(&t)});

        return t;
    }
};

/// This is used to filter collision on shapes. It affects shape-vs-shape collision
/// and shape-versus-query collision (such as WorldCastRay).
pub const Filter = struct {
    /// The collision category bits. Normally you would just set one bit. The category bits should
    /// represent your application object types. For example:
    /// enum MyCategories
    /// {
    ///    Static  = 0x00000001,
    ///    Dynamic = 0x00000002,
    ///    Debris  = 0x00000004,
    ///    Player  = 0x00000008,
    ///    // etc
    /// };
    category_bits: u64,

    /// The collision mask bits. This states the categories that this
    /// shape would accept for collision.
    /// For example, you may want your player to only collide with static objects
    /// and other players.
    /// maskBits = Static | Player;
    mask_bits: u64,

    /// Collision groups allow a certain group of objects to never collide (negative)
    /// or always collide (positive). A group index of zero has no effect. Non-zero group filtering
    /// always wins against the mask bits.
    /// For example, you may want ragdolls to collide with other ragdolls but you don't want
    /// ragdoll self-collision. In this case you would give each ragdoll a unique negative group index
    /// and apply that group index to all shapes on the ragdoll.
    group_index: u64,
};

/// Axis-aligned bounding box
pub const AABB = struct {
    lower_bound: Point,
    upper_bound: Point,

    pub fn init(lower_bound: Point, upper_bound: Point) AABB {
        return AABB{
            .lower_bound = lower_bound,
            .upper_bound = upper_bound,
        };
    }

    pub fn getCenter(self: *const AABB) Point {
        return Point.init(0.5 * (self.lower_bound.x + self.upper_bound.x), 0.5 * (self.lower_bound.y + self.upper_bound.y));
    }
};

/// Shape type
pub const ShapeType = enum {
    /// A circle with an offset
    Circle,

    /// A capsule is an extruded circle
    Capsule,

    /// A line segment
    Segment,

    /// A convex polygon
    Polygon,

    /// A line segment owned by a chain shape
    ChainSegment,
};
